/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Tristan Hume - <trishume@gmail.com> -
* Fix for Bug 2369 [Workbench] Would like to be able to save workspace without exiting
* Implemented workbench auto-save to correctly restore state in case of crash.
*******************************************************************************/
package org.eclipse.ui.internal.dialogs;
import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.layout.LayoutConstants;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.IntegerFieldEditor;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.jface.util.OpenStrategy;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.IPreferenceConstants;
import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.WorkbenchWindow;
import org.eclipse.ui.internal.util.PrefUtil;
/**
* Generic workbench main preference page.
*/
public class WorkbenchPreferencePage extends PreferencePage implements
IWorkbenchPreferencePage {
private Button stickyCycleButton;
private Button doubleClickButton;
private Button singleClickButton;
private Button selectOnHoverButton;
private Button openAfterDelayButton;
private Button showUserDialogButton;
private IntegerFieldEditor saveInterval;
private boolean openOnSingleClick;
private boolean selectOnHover;
private boolean openAfterDelay;
private Button showHeapStatusButton;
protected static int MAX_SAVE_INTERVAL = 9999;
@Override
protected Control createContents(Composite parent) {
// @issue if the product subclasses this page, then it should provide
// the help content
PlatformUI.getWorkbench().getHelpSystem().setHelp(parent,
IWorkbenchHelpContextIds.WORKBENCH_PREFERENCE_PAGE);
Composite composite = createComposite(parent);
createSettings(composite);
createSpace(composite);
createOpenModeGroup(composite);
applyDialogFont(composite);
return composite;
}
/**
* Create the buttons at the top of the preference page.
* @param composite
*/
protected void createSettings(Composite composite) {
createShowUserDialogPref(composite);
createStickyCyclePref(composite);
createHeapStatusPref(composite);
createSaveIntervalGroup(composite);
}
/**
* Create the widget for the user dialog preference.
*
* @param composite
*/
protected void createShowUserDialogPref(Composite composite) {
showUserDialogButton = new Button(composite, SWT.CHECK);
showUserDialogButton.setText(WorkbenchMessages.WorkbenchPreference_RunInBackgroundButton);
showUserDialogButton.setToolTipText(WorkbenchMessages.WorkbenchPreference_RunInBackgroundToolTip);
showUserDialogButton.setSelection(WorkbenchPlugin.getDefault()
.getPreferenceStore().getBoolean(
IPreferenceConstants.RUN_IN_BACKGROUND));
}
/**
* Create the widget for the heap status preference.
*
* @param composite
*/
protected void createHeapStatusPref(Composite composite) {
showHeapStatusButton = new Button(composite, SWT.CHECK);
showHeapStatusButton.setText(WorkbenchMessages.WorkbenchPreference_HeapStatusButton);
showHeapStatusButton.setToolTipText(WorkbenchMessages.WorkbenchPreference_HeapStatusButtonToolTip);
showHeapStatusButton.setSelection(PrefUtil.getAPIPreferenceStore().getBoolean(
IWorkbenchPreferenceConstants.SHOW_MEMORY_MONITOR));
}
/**
* Creates the composite which will contain all the preference controls for
* this page.
*
* @param parent
* the parent composite
* @return the composite for this page
*/
protected Composite createComposite(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
composite.setLayout(layout);
composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL
| GridData.HORIZONTAL_ALIGN_FILL));
return composite;
}
protected void createStickyCyclePref(Composite composite) {
stickyCycleButton = new Button(composite, SWT.CHECK);
stickyCycleButton.setText(WorkbenchMessages.WorkbenchPreference_stickyCycleButton);
stickyCycleButton.setSelection(getPreferenceStore().getBoolean(
IPreferenceConstants.STICKY_CYCLE));
}
/**
* Create a composite that contains entry fields specifying save interval
* preference.
*
* @param composite
* the Composite the group is created in.
*/
private void createSaveIntervalGroup(Composite composite) {
Composite groupComposite = new Composite(composite, SWT.LEFT);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
groupComposite.setLayout(layout);
GridData gd = new GridData();
gd.horizontalAlignment = GridData.FILL;
gd.grabExcessHorizontalSpace = true;
groupComposite.setLayoutData(gd);
saveInterval = new IntegerFieldEditor(IPreferenceConstants.WORKBENCH_SAVE_INTERVAL,
WorkbenchMessages.WorkbenchPreference_workbenchSaveInterval, groupComposite);
// @issue we should drop our preference constant and let clients use
// core's pref. ours is not up-to-date anyway if someone changes this
// interval directly thru core api.
saveInterval.setPreferenceStore(getPreferenceStore());
saveInterval.setPage(this);
saveInterval.setTextLimit(Integer.toString(MAX_SAVE_INTERVAL).length());
saveInterval.setErrorMessage(NLS.bind(
WorkbenchMessages.WorkbenchPreference_workbenchSaveIntervalError, Integer.valueOf(MAX_SAVE_INTERVAL)));
saveInterval.setValidateStrategy(StringFieldEditor.VALIDATE_ON_KEY_STROKE);
saveInterval.setValidRange(0, MAX_SAVE_INTERVAL);
saveInterval.load();
saveInterval.setPropertyChangeListener(event -> {
if (event.getProperty().equals(FieldEditor.IS_VALID)) {
setValid(saveInterval.isValid());
}
});
}
protected void createOpenModeGroup(Composite composite) {
Font font = composite.getFont();
Group buttonComposite = new Group(composite, SWT.LEFT);
GridLayout layout = new GridLayout();
buttonComposite.setLayout(layout);
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
| GridData.GRAB_HORIZONTAL);
buttonComposite.setLayoutData(data);
buttonComposite.setText(WorkbenchMessages.WorkbenchPreference_openMode);
String label = WorkbenchMessages.WorkbenchPreference_doubleClick;
doubleClickButton = createRadioButton(buttonComposite, label);
doubleClickButton.addSelectionListener(widgetSelectedAdapter(e -> selectClickMode(singleClickButton.getSelection())));
doubleClickButton.setSelection(!openOnSingleClick);
label = WorkbenchMessages.WorkbenchPreference_singleClick;
singleClickButton = createRadioButton(buttonComposite, label);
singleClickButton.addSelectionListener(widgetSelectedAdapter(e -> selectClickMode(singleClickButton.getSelection())));
singleClickButton.setSelection(openOnSingleClick);
label = WorkbenchMessages.WorkbenchPreference_singleClick_SelectOnHover;
selectOnHoverButton = new Button(buttonComposite, SWT.CHECK | SWT.LEFT);
selectOnHoverButton.setText(label);
selectOnHoverButton.setEnabled(openOnSingleClick);
selectOnHoverButton.setSelection(selectOnHover);
selectOnHoverButton.addSelectionListener(widgetSelectedAdapter(e -> selectOnHover = selectOnHoverButton.getSelection()));
data = new GridData();
data.horizontalIndent = LayoutConstants.getIndent();
selectOnHoverButton.setLayoutData(data);
label = WorkbenchMessages.WorkbenchPreference_singleClick_OpenAfterDelay;
openAfterDelayButton = new Button(buttonComposite, SWT.CHECK | SWT.LEFT);
openAfterDelayButton.setText(label);
openAfterDelayButton.setEnabled(openOnSingleClick);
openAfterDelayButton.setSelection(openAfterDelay);
openAfterDelayButton.addSelectionListener(widgetSelectedAdapter(e -> openAfterDelay = openAfterDelayButton.getSelection()));
data = new GridData();
data.horizontalIndent = LayoutConstants.getIndent();
openAfterDelayButton.setLayoutData(data);
createNoteComposite(font, buttonComposite, WorkbenchMessages.Preference_note,
WorkbenchMessages.WorkbenchPreference_noEffectOnAllViews);
}
private void selectClickMode(boolean singleClick) {
openOnSingleClick = singleClick;
selectOnHoverButton.setEnabled(openOnSingleClick);
openAfterDelayButton.setEnabled(openOnSingleClick);
}
/**
* Utility method that creates a radio button instance and sets the default
* layout data.
*
* @param parent
* the parent for the new button
* @param label
* the label for the new button
* @return the newly-created button
*/
protected static Button createRadioButton(Composite parent, String label) {
Button button = new Button(parent, SWT.RADIO | SWT.LEFT);
button.setText(label);
return button;
}
/**
* Utility method that creates a combo box
*
* @param parent
* the parent for the new label
* @return the new widget
*/
protected static Combo createCombo(Composite parent) {
Combo combo = new Combo(parent, SWT.READ_ONLY);
GridData data = new GridData(GridData.FILL_HORIZONTAL);
data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
combo.setLayoutData(data);
return combo;
}
/**
* Utility method that creates a label instance and sets the default layout
* data.
*
* @param parent
* the parent for the new label
* @param text
* the text for the new label
* @return the new label
*/
protected static Label createLabel(Composite parent, String text) {
Label label = new Label(parent, SWT.LEFT);
label.setText(text);
GridData data = new GridData();
data.horizontalSpan = 1;
data.horizontalAlignment = GridData.FILL;
label.setLayoutData(data);
return label;
}
/**
* Creates a tab of one horizontal spans.
*
* @param parent
* the parent in which the tab should be created
*/
protected static void createSpace(Composite parent) {
Label vfiller = new Label(parent, SWT.LEFT);
GridData gridData = new GridData();
gridData = new GridData();
gridData.horizontalAlignment = GridData.BEGINNING;
gridData.grabExcessHorizontalSpace = false;
gridData.verticalAlignment = GridData.CENTER;
gridData.grabExcessVerticalSpace = false;
vfiller.setLayoutData(gridData);
}
/**
* Returns preference store that belongs to the our plugin.
*
* @return the preference store for this plugin
*/
@Override
protected IPreferenceStore doGetPreferenceStore() {
return WorkbenchPlugin.getDefault().getPreferenceStore();
}
/**
* @see IWorkbenchPreferencePage
*/
@Override
public void init(IWorkbench aWorkbench) {
IPreferenceStore store = getPreferenceStore();
openOnSingleClick = store
.getBoolean(IPreferenceConstants.OPEN_ON_SINGLE_CLICK);
selectOnHover = store.getBoolean(IPreferenceConstants.SELECT_ON_HOVER);
openAfterDelay = store
.getBoolean(IPreferenceConstants.OPEN_AFTER_DELAY);
}
/**
* The default button has been pressed.
*/
@Override
protected void performDefaults() {
IPreferenceStore store = getPreferenceStore();
saveInterval.loadDefault();
stickyCycleButton.setSelection(store
.getBoolean(IPreferenceConstants.STICKY_CYCLE));
openOnSingleClick = store
.getDefaultBoolean(IPreferenceConstants.OPEN_ON_SINGLE_CLICK);
selectOnHover = store
.getDefaultBoolean(IPreferenceConstants.SELECT_ON_HOVER);
openAfterDelay = store
.getDefaultBoolean(IPreferenceConstants.OPEN_AFTER_DELAY);
singleClickButton.setSelection(openOnSingleClick);
doubleClickButton.setSelection(!openOnSingleClick);
selectOnHoverButton.setSelection(selectOnHover);
openAfterDelayButton.setSelection(openAfterDelay);
selectOnHoverButton.setEnabled(openOnSingleClick);
openAfterDelayButton.setEnabled(openOnSingleClick);
stickyCycleButton.setSelection(store
.getDefaultBoolean(IPreferenceConstants.STICKY_CYCLE));
showUserDialogButton.setSelection(store.getDefaultBoolean(
IPreferenceConstants.RUN_IN_BACKGROUND));
showHeapStatusButton.setSelection(PrefUtil.getAPIPreferenceStore().getDefaultBoolean(
IWorkbenchPreferenceConstants.SHOW_MEMORY_MONITOR));
super.performDefaults();
}
/**
* The user has pressed Ok. Store/apply this page's values appropriately.
*/
@Override
public boolean performOk() {
IPreferenceStore store = getPreferenceStore();
// store the keep cycle part dialogs sticky preference
store.setValue(IPreferenceConstants.STICKY_CYCLE, stickyCycleButton
.getSelection());
store.setValue(IPreferenceConstants.OPEN_ON_SINGLE_CLICK,
openOnSingleClick);
store.setValue(IPreferenceConstants.SELECT_ON_HOVER, selectOnHover);
store.setValue(IPreferenceConstants.OPEN_AFTER_DELAY, openAfterDelay);
store.setValue(IPreferenceConstants.RUN_IN_BACKGROUND,
showUserDialogButton.getSelection());
store.setValue(IPreferenceConstants.WORKBENCH_SAVE_INTERVAL, saveInterval.getIntValue());
PrefUtil.getAPIPreferenceStore().setValue(IWorkbenchPreferenceConstants.SHOW_MEMORY_MONITOR, showHeapStatusButton.getSelection());
updateHeapStatus(showHeapStatusButton.getSelection());
int singleClickMethod = openOnSingleClick ? OpenStrategy.SINGLE_CLICK
: OpenStrategy.DOUBLE_CLICK;
if (openOnSingleClick) {
if (selectOnHover) {
singleClickMethod |= OpenStrategy.SELECT_ON_HOVER;
}
if (openAfterDelay) {
singleClickMethod |= OpenStrategy.ARROW_KEYS_OPEN;
}
}
OpenStrategy.setOpenMethod(singleClickMethod);
PrefUtil.savePrefs();
return true;
}
/**
* Show or hide the heap status based on selection.
* @param selection
*/
private void updateHeapStatus(boolean selection) {
IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows();
for (IWorkbenchWindow window : windows) {
if(window instanceof WorkbenchWindow){
((WorkbenchWindow) window).showHeapStatus(selection);
}
}
}
}